package com.im.service.measureReport.smo;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletRequest;
import javax.transaction.Transactional;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.im.MDA;
import com.im.service.contract.dao.IContractItemOperDAO;
import com.im.service.contract.dao.IContractItemQueryDAO;
import com.im.service.dto.BaseException;
import com.im.service.dto.Contract;
import com.im.service.dto.ContractClause;
import com.im.service.dto.ContractItem;
import com.im.service.dto.DeclarePayRela;
import com.im.service.dto.ImplementProject;
import com.im.service.dto.MeteDeclare;
import com.im.service.dto.MetePay;
import com.im.service.dto.PageQuery;
import com.im.service.dto.SearchOption;
import com.im.service.dto.Staff;
import com.im.service.measureReport.dao.IMeasurementReportDAO;
import com.im.service.meteDeclare.dao.IMeteDeclareOperDAO;
import com.im.service.meteDeclare.dao.IMeteDeclareQueryDAO;
import com.im.service.metePay.dao.IMetePayOperDAO;
import com.im.service.metePay.dao.IMetePayQueryDAO;
import com.im.service.model.ContractAndItemVo;
import com.im.service.model.ContractItemVo;
import com.im.service.model.MetePayVo;
import com.im.util.JsonUtil;
import com.im.util.ReturnsUtil;
import com.im.util.StringUtil;

import net.sf.json.JSONObject;

@Service
public class MeasurementReportSMOImpl implements IMeasurementReportSMO {

	@Autowired
	private IMeteDeclareQueryDAO meteDeclareQueryDAO;
	@Autowired
	private IMeteDeclareOperDAO meteDeclareOperDAO;
	@Autowired
	private IContractItemQueryDAO contractItemQueryDAO;
	@Autowired
	private IContractItemOperDAO contractItemOperDAO;
	@Autowired
	private IMeasurementReportDAO measurementReportDAO;
	@Autowired
	private IMetePayOperDAO metePayOperDAO;
	@Autowired
	private IMetePayQueryDAO metePayQueryDAO;
	private static final Logger logger = LogManager.getLogger(MeasurementReportSMOImpl.class);

	@Override
	public PageQuery<ContractItemVo> queryContractItem(String inJson) {

		PageQuery<ContractItemVo> page = null;
		JSONObject jsonObj = JSONObject.fromObject(inJson);
		if (jsonObj.containsKey(MDA.PAGE_QUERY_INFO)) {
			JSONObject pageInfo = jsonObj.getJSONObject(MDA.PAGE_QUERY_INFO);
			page = JsonUtil.jsonToBean(pageInfo.toString(), PageQuery.class);
			jsonObj.remove(MDA.PAGE_QUERY_INFO);
		}
		ContractItemVo contractItemVo = JsonUtil.jsonToBean(jsonObj.toString(), ContractItemVo.class);

		Map<String, Object> param = new HashMap<String, Object>();
		param.put("contractItemVo", contractItemVo);
		if (page != null) {
			param.put("page", page);
			PageHelper.startPage(page.getPageNumber(), page.getPageSize());
		}
		List<ContractItemVo> list = measurementReportDAO.queryContractItem(param);

		// List<ContractItemVo>
		// list=measurementReportDAO.queryContractItem(contractItemVo,searchOption);

		if (page != null) {
			page.setTotalPages(((Page<ContractItemVo>) list).getPages());
			page.setTotal(((Page<ContractItemVo>) list).getTotal());
		} else {
			page = new PageQuery<ContractItemVo>();
		}
		page.setRows(list);

		return page;
	}

	@Override
	public List<ContractItemVo> queryContractItemDetailByContractId(Contract contract) {
		return measurementReportDAO.queryContractItemDetailByContractId(contract);
	}

	@Override
	public void updateDeclarePay(ContractItemVo contractItem,HttpServletRequest request) {
		// 1.有申报记录 declareId 不为空则更新 没有申报记录 则新增
		MeteDeclare meteDeclare = new MeteDeclare();
		meteDeclare.setPayment(new BigDecimal(contractItem.getNowPayment()));
		meteDeclare.setPaymentRatio(new BigDecimal(contractItem.getNowPaymentRatio()));
		if(StringUtil.isEmpty(contractItem.getDeclareId())){
			//获取登录员工
			Object staffObj = request.getSession().getAttribute("loginedStaff");
			String staffId = "";
			if(staffObj != null){
				Staff staff = (Staff) staffObj;
				staffId = staff.getStaffId();
			}
			String declareId = UUID.randomUUID().toString();
			
			meteDeclare.setDeclareId(declareId);
			meteDeclare.setContractItemId(contractItem.getContractItemId());
			meteDeclare.setAmount(contractItem.getAmount());
			meteDeclare.setTotal(contractItem.getItemTotal());
			meteDeclare.setDeclarer(staffId);
			meteDeclare.setStatusCd(10);
			measurementReportDAO.addMeasureReport(meteDeclare);
			
			contractItem.setDeclareId(declareId);
		}else{
			meteDeclare.setDeclareId(contractItem.getDeclareId());
			measurementReportDAO.updateMeasureReport(meteDeclare);
		}
		
		
		// 2.有支付记录 payId 不为空则更新 没有支付记录 则新增
		MetePay metePay = new MetePay();
		metePay.setPayRatio(contractItem.getNowPaymentRatio());
		metePay.setPayment(contractItem.getNowPayment());
		metePay.setDescription(contractItem.getDescription());
		if (StringUtil.isEmpty(contractItem.getPayId())) {
			// 新增
			metePay.setPayId(UUID.randomUUID().toString());
			metePay.setStatusCd(20);
			metePay.setPayCode("not Null");
			metePayOperDAO.addMetePay(metePay);
			if (new BigDecimal(0).compareTo(contractItem.getPayment()) != 0) {
				List<MetePayVo> metePayList = metePayQueryDAO
						.queryMetePayListByContItemId(contractItem.getContractItemId());
				if (metePayList != null) {
					metePay.setCnt(metePayList.size());
				}
			} else {
				metePay.setCnt(1);
			}
			DeclarePayRela dpr = new DeclarePayRela();
			dpr.setDpayRelaId(UUID.randomUUID().toString());
			dpr.setDeclareId(contractItem.getDeclareId());
			dpr.setPayId(metePay.getPayId());
			metePayOperDAO.addDeclarePayRela(dpr);
		} else {
			// 修改
			metePay.setPayId(contractItem.getPayId());
			metePayOperDAO.updateMetePay(metePay);
		}
	}

	@Override
	public List<ImplementProject> queryImplProjectList() {
		return measurementReportDAO.queryImplProject();
	}

	@Override
	public List<Contract> queryContractListByImplProject(ImplementProject implementProject) {
		return measurementReportDAO.queryContractListByImplProject(implementProject);
	}

	@Override
	public List<ContractClause> queryContractClauseListByContract(Contract contract) {
		return measurementReportDAO.queryContractClauseListByContract(contract);
	}

	@Override
	public List<ContractItem> queryContractItemListByContractClause(ContractClause contractClause) {
		return measurementReportDAO.queryContractItemListByContractClause(contractClause);
	}

	@Override
	public List<ContractItem> queryContractItemInfo(ContractItem contractItem) {
		return measurementReportDAO.queryContractItemInfo(contractItem);
	}

	@Override
	@Transactional
	public int addMeasureReport(MeteDeclare meteDeclare) {
		int count = measurementReportDAO.addMeasureReport(meteDeclare);
		// 修改合同分项的已支付金额
		measurementReportDAO.updateContractItemPayment(meteDeclare);
		return 0;
	}

	@Override
	@Transactional
	public int saveMeasureReport(MeteDeclare meteDeclare) {
		int count = measurementReportDAO.updateMeasureReport(meteDeclare);
		// 针对修改的payment，需要将原来的payment减掉以后才能再加上去才行
		meteDeclare.setPayment(meteDeclare.getPayment().subtract(meteDeclare.getOldPayment()));
		measurementReportDAO.updateContractItemPayment(meteDeclare);
		return count;
	}

	@Override
	public int delMeasureReport(MeteDeclare meteDeclare) {
		int count = measurementReportDAO.delMeasureReport(meteDeclare);
		BigDecimal payment = meteDeclare.getPayment();
		payment = payment.multiply(new BigDecimal(-1));
		meteDeclare.setPayment(payment);
		measurementReportDAO.updateContractItemPayment(meteDeclare);
		return 0;
	}

	public PageQuery<ContractItemVo> queryExamineContractItem(ContractItemVo contractItemVo,

			SearchOption searchOption) {
		PageHelper.startPage(searchOption.getPageNumber(), searchOption.getPageSize());
		List<ContractItemVo> list = measurementReportDAO.queryExamineContractItem(contractItemVo, searchOption);
		Page<ContractItemVo> data = (Page<ContractItemVo>) list;
		PageQuery<ContractItemVo> page = new PageQuery<ContractItemVo>();
		page.setRows(list);
		page.setTotal(data.getTotal());
		return page;
	}

	@Override
	public String examineMeasureReport(String jsonStr) {
		// 1.json格式校验
		if (!JsonUtil.jsonValidate(jsonStr)) {
			throw new BaseException(new StringBuffer().append("字符串： ").append(jsonStr).append("不符合JSON格式").toString());
		}
		try {
			JSONObject jsonObj = JSONObject.fromObject(jsonStr);
			String errorMsg = "获取审定合同分项入参时：";
			String contractClauseId = JsonUtil.getNotNullStringFromJSON(jsonObj, "contractClauseId", errorMsg);
			Integer statusCd = JsonUtil.getIntegerFromJSON(jsonObj, "statusCd", errorMsg);
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("contractClauseId", contractClauseId);
			List<MeteDeclare> metelist = meteDeclareQueryDAO.queryEaxmineMeteDeclareList(param);
			for (MeteDeclare meteDeclare : metelist) {
				if (statusCd == 0) {
					meteDeclare.setStatusCd(20);
					// 更新状态为审核通过
					meteDeclareOperDAO.updateMeteDeclare(meteDeclare);
					//
					ContractAndItemVo itemVo = new ContractAndItemVo();
					itemVo.setConItemId(meteDeclare.getConItemId());
					param.put("contractItem", itemVo);
					// 查询计量申报对应的合同分项
					itemVo = contractItemQueryDAO.queryContractItemDetail(param);
					itemVo.setPayment(itemVo.getPayment().add(meteDeclare.getPayment()));
					itemVo.setPaymentRatio(itemVo.getPaymentRatio().add(meteDeclare.getPaymentRatio()));
					if (itemVo.getUnpaid().compareTo(meteDeclare.getPayment()) == 0) {
						itemVo.setStatusCd(MDA.CONTRACT_ITEM_STATUS_CD_PAYED.toString());
					} else {
						itemVo.setStatusCd(itemVo.getStatus());
					}
					itemVo.setUnpaid(itemVo.getUnpaid().subtract(meteDeclare.getPayment()));
					// 更新分项已支付比例、已支付金额、剩余金额 和状态
					contractItemOperDAO.updateContractItem(itemVo);
				} else {
					meteDeclare.setStatusCd(30);
					meteDeclareOperDAO.updateMeteDeclare(meteDeclare);
				}
			}
			return ReturnsUtil.returnSuccess(new JSONObject()).toString();
		} catch (BaseException e) {
			if (logger.isErrorEnabled()) {
				logger.error(e.getStackTrace());
			}
			return ReturnsUtil.returnFailure(e.getMessage());
		} catch (Exception e) {
			if (logger.isErrorEnabled()) {
				logger.error(ReturnsUtil.getStackTrackMessage(e));
			}
			return ReturnsUtil.returnException("审定计量申报信息失败", e).toString();
		}
	}
}
